#include "modbus_device_socket.h"
#include <sys/socket.h> 


extern uint8_t test_data[2048];
extern uint16_t test_data_size;
extern int32_t test_status;
extern int accept_fd;

/********************************** define **************************************/
static int32_t device_init(void *handle);
static int32_t device_send_data(void *com_handle, uint8_t *data, uint16_t length);
static int32_t device_read_input_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count);
static int32_t device_read_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count);
static int32_t device_write_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count);
static int32_t device_read_file(uint16_t file, uint32_t pack_num, uint8_t *data, uint16_t pack_len);
static int32_t device_write_file(uint16_t file, uint32_t pack_num, uint8_t *data, uint16_t pack_len);


static MODBUS_Data_Buffer_t tx_buffer = 
{
  test_data,
  &test_data_size,
  (int32_t *)&test_status,
};

static MODBUS_Data_Buffer_t rx_buffer = 
{
  test_data,
  &test_data_size,
  (int32_t *)&test_status,
};


static MODBUS_Reg_Count_t input_reg;
static MODBUS_Reg_Count_t hold_reg;

static uint16_t socket_reg_start_addr = 0x0000;
static uint16_t socket_reg_count = 0x0100;

static uint8_t device_id = 0x01;

uint8_t modbus_d1_buff[0x0100 * 2];


MODBUS_User_Reg_t modbus_device_socket = 
{
  &modbus_device_socket,
  device_init,
};


static int32_t device_init(void *handle)
{
  MODBUS_User_Reg_t *device_handle = (MODBUS_User_Reg_t *)handle;

  device_handle->read_input_reg = device_read_input_reg;
  device_handle->read_hold_reg = device_read_hold_reg;
  device_handle->write_hold_reg = device_write_hold_reg;
  device_handle->read_user_file = device_read_file;
  device_handle->write_user_file = device_write_file;

  device_handle->send_rtu = device_send_data;
  device_handle->send_rtu_com = &accept_fd;
  device_handle->tx_buffer_rtu = &tx_buffer;
  device_handle->rx_buffer_rtu = &rx_buffer;

  device_handle->send_tcp = device_send_data;
  device_handle->send_tcp_com = &accept_fd;
  device_handle->tx_buffer_tcp = &tx_buffer;
  device_handle->rx_buffer_tcp = &rx_buffer;

  device_handle->modbus_device_id = &device_id;
  
  input_reg.start_addr = &socket_reg_start_addr;
  input_reg.count = &socket_reg_count;
  device_handle->input_reg = &input_reg;
  
  hold_reg.start_addr = &socket_reg_start_addr;
  hold_reg.count = &socket_reg_count;
  device_handle->hold_reg = &hold_reg;

  return 0;
}


static int32_t device_send_data(void *com_handle, uint8_t *data, uint16_t length)
{
  int *test_com = (int *)com_handle;

  return send(*test_com, data, length, 0);
}


/**
  * @brief  读输入寄存器(用户代码)
  * @note   1个寄存器占2Byte
  * @param  reg_addr: 寄存器地址
  * @param  reg_data: 寄存器数据
  * @param  reg_count: 寄存器数量
  * @retval 0
  */
static int32_t device_read_input_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count)
{
  switch (reg_addr)
  {    
    case D1_HR_PRODUCT_ID:
      break;
    
    default:
      break;
  }
  
  memcpy(reg_data, (modbus_d1_buff + reg_addr * 2), reg_count * 2);
  
  return 0;
}


/**
  * @brief  读保持寄存器(用户代码)
  * @note   1个寄存器占2Byte
  * @param  reg_addr: 寄存器地址
  * @param  reg_data: 寄存器数据
  * @param  reg_count: 寄存器数量
  * @retval 0
  */
static int32_t device_read_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count)
{
  switch (reg_addr)
  {
    default:
      break;
  }
  
  memcpy(reg_data, (modbus_d1_buff + reg_addr * 2), reg_count * 2);
  
  return 0;
}


/**
  * @brief  写保持寄存器(用户代码)
  * @note   1个寄存器占2Byte
  * @param  reg_addr: 寄存器地址
  * @param  reg_data: 寄存器数据
  * @param  reg_count: 寄存器数量
  * @retval 0
  */
static int32_t device_write_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count)
{
  int32_t res = MODBUS_SUCCEED;
  switch (reg_addr)
  {
    default:
      break;
  }
  
  memcpy((modbus_d1_buff + reg_addr * 2), reg_data, reg_count * 2);
  
  return res;
}



static int32_t device_read_file(uint16_t file, uint32_t pack_num, uint8_t *data, uint16_t pack_len)
{
  uint16_t i = 0;
  for (i = 0; i < 1024; i++)
  {
    data[i] = i;
  }
  
  return 0;
}



static int32_t device_write_file(uint16_t file, uint32_t pack_num, uint8_t *data, uint16_t pack_len)
{
  
  return 0;
}






